iT邦幫忙

2021 iThome 鐵人賽

DAY 17
0
自我挑戰組

來解數學跟刷圖論跟幾何程式題或者我突然想研究的主題系列 第 17

了解 Leetcode: 1627. Graph Connectivity With Threshold 那兩層For迴圈

  • 分享至 

  • xImage
  •  

再重新敘述一次問題:

假設n = 878,代表說現在給你1到878個點,在沒有資訊前,你看每個點都是一座孤島,但只要倆倆孤島的編號滿足兩者的公因數z大於閾值(threshold),就代表他倆有連線

接著就是問你在找到這878個孤島之間的連線後,我給你倆倆孤島的編號,問你我能不能從孤島4走到孤島877啊?麻煩快點告訴我謝謝。
 
 
 
 

迴圈的意義

這個回圈在做的事情就是找此時點與點之間的連線,用並查集的做法意味著:我不需要知道我要怎麼走才能從點4走到點877,我只要知道點4跟點877是都有跟同一個點連線就行,因為這樣代表他們之間也有連線,也就代表我能從點4走到點877。

for (int z = threshold + 1; 2*z <= n; z++)
    for (int m = 2; m*z <= n; m++) 
        unionfunc(z, m*z);

 
 

那麼for的起始條件以及終止點條件的設定由來?

有個條件

z > threshold

z就是公因數,也是開始找的孤島編號,假設n = 878,threshold = 95,代表說我要找的公因數,必須大於threshold,從96開始,也代表說孤島1~孤島95不可能有連線,因為他們沒有大於等於96的因數。

所以第一層迴圈起始條件設為這樣

z = threshold + 1

 
 
再來是終止條件。

10
= 1 x 10
= 2 x 5
= 5 x 2
= 10 x 1

像是在找10的因數時,不需要全部找完,只要找到一半,因數相乘互換的部分,就可以找到所有10的因數,而中止點恰好是10/2。所以在878個孤島中,從threshld+1的編號開始找時,只需要去找z <= 878/2的編號就行。 那因為除法比乘法慢,所以改成等價的

2*z <= n

 
 
 

第一層for已經幫我確認過z是大於threshold的。再來,題目說,若孤島倆倆的編號同時具有z這個因數,他們就有連線。

什麼時候會有相同的因數?z的倍數保證他一定也有z的因數,所以從編號96與編號2*96,和編號3*96..之間一定有連線。所以這裡就把孤島96和小於孤島總數的96倍數,連接起來,因此起始與終止條件設為

m = 2; m*z <= n

 
 
 

雖然常常感嘆他們都是怎麼想到這些解法的,但喲西喲西,又了解了一點東西。
 
 
 

參考:
https://leetcode.com/problems/graph-connectivity-with-threshold/discuss/933034/RubyPython-Union-Find-with-explanation.-Short-code.


上一篇
Leetcode: 1627. Graph Connectivity With Threshold
下一篇
簡單了解VR頭盔中,重要且相輔相成的Eye tracking 與Foveated Rendering技術 2
系列文
來解數學跟刷圖論跟幾何程式題或者我突然想研究的主題33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言